```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>二叉树的最近公共祖先 - 算法可视化</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', sans-serif;
            background-color: #f8fafc;
            color: #1e293b;
        }
        .hero-gradient {
            background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
        }
        .code-block {
            background-color: #1e293b;
            border-radius: 0.5rem;
            box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
        }
        .card-hover {
            transition: all 0.3s ease;
        }
        .card-hover:hover {
            transform: translateY(-5px);
            box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
        }
        .highlight {
            position: relative;
        }
        .highlight::after {
            content: '';
            position: absolute;
            bottom: 0.1em;
            left: 0;
            width: 100%;
            height: 0.4em;
            background-color: #a5b4fc;
            opacity: 0.4;
            z-index: -1;
            border-radius: 2px;
        }
        .node circle {
            fill: #8b5cf6;
            stroke: #7c3aed;
            stroke-width: 2px;
        }
        .node text {
            font-size: 12px;
            fill: white;
        }
        .link {
            fill: none;
            stroke: #c4b5fd;
            stroke-width: 1.5px;
        }
        .highlight-node circle {
            fill: #ec4899;
            stroke: #db2777;
        }
    </style>
</head>
<body class="min-h-screen">
    <!-- Hero Section -->
    <div class="hero-gradient text-white py-20 px-6">
        <div class="max-w-4xl mx-auto text-center">
            <h1 class="text-4xl md:text-5xl font-bold mb-6 font-serif">二叉树的最近公共祖先</h1>
            <p class="text-xl md:text-2xl opacity-90 mb-8">探索树形数据结构中最优雅的递归解法</p>
            <div class="flex justify-center space-x-4">
                <span class="px-4 py-2 bg-white text-indigo-600 rounded-full font-medium">递归</span>
                <span class="px-4 py-2 bg-white text-indigo-600 rounded-full font-medium">深度优先搜索</span>
                <span class="px-4 py-2 bg-white text-indigo-600 rounded-full font-medium">二叉树</span>
            </div>
        </div>
    </div>

    <!-- Main Content -->
    <div class="max-w-6xl mx-auto px-6 py-12">
        <!-- Problem Description -->
        <div class="grid md:grid-cols-2 gap-12 mb-16">
            <div class="bg-white rounded-xl shadow-lg p-8 card-hover">
                <div class="flex items-center mb-6">
                    <div class="bg-indigo-100 p-3 rounded-full mr-4">
                        <i class="fas fa-tree text-indigo-600 text-xl"></i>
                    </div>
                    <h2 class="text-2xl font-bold text-gray-800">题目描述</h2>
                </div>
                <div class="prose max-w-none text-gray-700">
                    <p>给定一个二叉树和树中的两个节点 p 和 q，找到该树中这两个节点的<strong class="highlight">最近公共祖先</strong>（LCA）。</p>
                    <p>最近公共祖先是指：对于有根树 T 的两个节点 p、q，最近公共祖先表示为一个节点 x，满足 x 是 p、q 的祖先且 x 的深度尽可能大（一个节点也可以是它自己的祖先）。</p>
                    <p class="bg-indigo-50 p-4 rounded-lg border-l-4 border-indigo-500">
                        <i class="fas fa-lightbulb text-indigo-600 mr-2"></i>
                        <strong>示例：</strong>在树 [3,5,1,6,2,0,8,null,null,7,4] 中，节点 5 和节点 1 的最近公共祖先是节点 3。
                    </p>
                </div>
            </div>

            <!-- Visualization -->
            <div class="bg-white rounded-xl shadow-lg p-8 card-hover">
                <div class="flex items-center mb-6">
                    <div class="bg-purple-100 p-3 rounded-full mr-4">
                        <i class="fas fa-project-diagram text-purple-600 text-xl"></i>
                    </div>
                    <h2 class="text-2xl font-bold text-gray-800">可视化示例</h2>
                </div>
                <div class="mermaid">
                    graph TD
                    3 --> 5
                    3 --> 1
                    5 --> 6
                    5 --> 2
                    2 --> 7
                    2 --> 4
                    1 --> 0
                    1 --> 8
                    style 5 fill:#ec4899,stroke:#db2777
                    style 1 fill:#ec4899,stroke:#db2777
                    style 3 fill:#8b5cf6,stroke:#7c3aed
                </div>
                <p class="mt-4 text-gray-600 text-sm flex items-center">
                    <i class="fas fa-info-circle mr-2 text-indigo-500"></i>
                    在上图中，紫色节点 3 是红色节点 5 和 1 的最近公共祖先
                </p>
            </div>
        </div>

        <!-- Solution Section -->
        <div class="grid md:grid-cols-2 gap-12 mb-16">
            <!-- Algorithm Explanation -->
            <div class="bg-white rounded-xl shadow-lg p-8 card-hover">
                <div class="flex items-center mb-6">
                    <div class="bg-green-100 p-3 rounded-full mr-4">
                        <i class="fas fa-brain text-green-600 text-xl"></i>
                    </div>
                    <h2 class="text-2xl font-bold text-gray-800">解题思路</h2>
                </div>
                <div class="prose max-w-none text-gray-700">
                    <ol class="list-decimal pl-6 space-y-4">
                        <li>
                            <strong>递归遍历树</strong>：从根节点开始递归遍历整棵树
                        </li>
                        <li>
                            <strong>基准情况</strong>：如果当前节点是 p 或 q，或者为空，则返回当前节点
                        </li>
                        <li>
                            <strong>递归查询</strong>：分别在左右子树中查找 p 和 q
                            <ul class="list-disc pl-6 mt-2 space-y-1">
                                <li>如果在左右子树中都找到了结果，说明当前节点就是 LCA</li>
                                <li>如果只有一边有结果，则返回该结果</li>
                            </ul>
                        </li>
                    </ol>
                    <div class="mt-6 p-4 bg-amber-50 rounded-lg border-l-4 border-amber-400">
                        <div class="flex">
                            <i class="fas fa-clock text-amber-600 mt-1 mr-2"></i>
                            <div>
                                <p class="font-semibold">复杂度分析</p>
                                <p>时间复杂度: O(n) - 需要遍历所有节点</p>
                                <p>空间复杂度: O(h) - 递归栈的深度等于树的高度</p>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <!-- Code Example -->
            <div class="bg-white rounded-xl shadow-lg overflow-hidden card-hover">
                <div class="flex items-center p-6 border-b border-gray-200">
                    <div class="bg-blue-100 p-3 rounded-full mr-4">
                        <i class="fas fa-code text-blue-600 text-xl"></i>
                    </div>
                    <h2 class="text-2xl font-bold text-gray-800">示例代码</h2>
                    <div class="ml-auto flex space-x-2">
                        <span class="px-2 py-1 bg-gray-100 text-gray-600 rounded-md text-sm">Python</span>
                    </div>
                </div>
                <div class="code-block p-6">
                    <pre class="text-gray-300 font-mono text-sm overflow-x-auto"><code>def lowestCommonAncestor(root, p, q):
    <span class="text-purple-400"># 基准情况：找到节点或空节点</span>
    <span class="text-blue-400">if</span> <span class="text-yellow-300">not</span> root <span class="text-blue-400">or</span> root == p <span class="text-blue-400">or</span> root == q:
        <span class="text-blue-400">return</span> root
    
    <span class="text-purple-400"># 递归查询左右子树</span>
    left = lowestCommonAncestor(root.left, p, q)
    right = lowestCommonAncestor(root.right, p, q)
    
    <span class="text-purple-400"># 如果两边都找到，当前节点就是LCA</span>
    <span class="text-blue-400">if</span> left <span class="text-blue-400">and</span> right:
        <span class="text-blue-400">return</span> root
    
    <span class="text-purple-400"># 返回非空的结果</span>
    <span class="text-blue-400">return</span> left <span class="text-blue-400">if</span> left <span class="text-blue-400">else</span> right</code></pre>
                </div>
            </div>
        </div>

        <!-- Detailed Explanation -->
        <div class="bg-white rounded-xl shadow-lg p-8 mb-16 card-hover">
            <div class="flex items-center mb-6">
                <div class="bg-rose-100 p-3 rounded-full mr-4">
                    <i class="fas fa-book-open text-rose-600 text-xl"></i>
                </div>
                <h2 class="text-2xl font-bold text-gray-800">算法深度解析</h2>
            </div>
            <div class="prose max-w-none text-gray-700">
                <div class="grid md:grid-cols-2 gap-6">
                    <div>
                        <h3 class="text-lg font-semibold text-gray-800 mb-3 flex items-center">
                            <i class="fas fa-search-minus text-indigo-500 mr-2"></i>
                            递归过程分解
                        </h3>
                        <p>算法的核心在于利用递归"自底向上"地查找：</p>
                        <ol class="list-decimal pl-6 space-y-2 mt-2">
                            <li>从根节点开始递归遍历</li>
                            <li>当遇到 p 或 q 时立即返回当前节点</li>
                            <li>递归比较左右子树的返回结果</li>
                            <li>如果两边都非空，当前节点就是LCA</li>
                        </ol>
                    </div>
                    <div>
                        <h3 class="text-lg font-semibold text-gray-800 mb-3 flex items-center">
                            <i class="fas fa-question-circle text-indigo-500 mr-2"></i>
                            常见疑问解答
                        </h3>
                        <ul class="list-disc pl-6 space-y-2">
                            <li>为什么一个节点可以是自己的祖先？</li>
                            <li>如果p是q的祖先会怎样？</li>
                            <li>如何处理树中不存在的节点？</li>
                        </ul>
                    </div>
                </div>

                <div class="mt-8 p-6 bg-blue-50 rounded-lg border-l-4 border-blue-500">
                    <div class="flex">
                        <i class="fas fa-lightbulb text-blue-600 mt-1 mr-3 text-xl"></i>
                        <div>
                            <h4 class="font-bold text-lg mb-2">关键洞察</h4>
                            <p>这个算法的精妙之处在于它巧妙地利用了递归的<b>回溯特性</b>。当我们在左右子树中都找到了目标节点时，当前递归层级的节点自然就是它们的最近公共祖先。这种解法将复杂的问题分解为简单的子问题，体现了<b>分治思想</b>的威力。</p>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- Visualization Section -->
        <div class="bg-white rounded-xl shadow-lg p-8 card-hover">
            <div class="flex items-center mb-6">
                <div class="bg-yellow-100 p-3 rounded-full mr-4">
                    <i class="fas fa-sitemap text-yellow-600 text-xl"></i>
                </div>
                <h2 class="text-2xl font-bold text-gray-800">递归调用过程可视化</h2>
            </div>
            <div class="mermaid">
                graph TD
                subgraph 递归调用栈
                A["lowestCommonAncestor(3,5,1)"] --> B["lowestCommonAncestor(5,5,1)"]
                A --> C["lowestCommonAncestor(1,5,1)"]
                B --> D["lowestCommonAncestor(6,5,1)"]
                B --> E["lowestCommonAncestor(2,5,1)"]
                E --> F["lowestCommonAncestor(7,5,1)"]
                E --> G["lowestCommonAncestor(4,5,1)"]
                C --> H["lowestCommonAncestor(0,5,1)"]
                C --> I["lowestCommonAncestor(8,5,1)"]
                end
                style A fill:#8b5cf6,stroke:#7c3aed
                style B fill:#10b981,stroke:#059669
                style C fill:#10b981,stroke:#059669
            </div>
            <div class="mt-6 grid md:grid-cols-2 gap-6">
                <div class="p-4 bg-green-50 rounded-lg">
                    <h4 class="font-semibold text-green-800 mb-2"><i class="fas fa-check-circle mr-2"></i>递归终止条件</h4>
                    <p class="text-sm text-gray-700">当递归到节点5或1时，直接返回该节点，因为它们是我们要找的目标节点。</p>
                </div>
                <div class="p-4 bg-purple-50 rounded-lg">
                    <h4 class="font-semibold text-purple-800 mb-2"><i class="fas fa-code-branch mr-2"></i>结果合并</h4>
                    <p class="text-sm text-gray-700">当左右子树都返回非空结果时，当前节点就是LCA（节点3）。</p>
                </div>
            </div>
        </div>
    </div>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            }
        });
    </script>
</body>
</html>
```